package com.lkeqi.usercenter.utils;/* by yours.tools - online tools website : yours.tools/zh/generatebtcwallets.html */
import org.bouncycastle.crypto.engines.SM4Engine;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
 
import java.util.Base64;
 
public class Sm4Util {
 
    // 示例密钥，实际应用中应使用安全的方式生成和存储密钥
    private static final String KEY = "0123456789abcdef"; 
    // 示例向量，实际应用中应使用安全的方式生成和存储初始化向量
    //需要确保KEY和IV保持16字节长度
    private static final String IV = "fedcba9876543210";
 
    /**
     * 使用 SM4 算法对明文进行加密。
     *
     * @param plainText 要加密的明文字符串
     * @return 加密后的 Base64 编码字符串
     * @throws Exception 如果加密过程中发生错误
     */
    public static String encrypt(String plainText) throws Exception {
        // 创建一个带填充的缓冲块密码器，使用 CBC 模式和 SM4 引擎
        PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new SM4Engine()));
        
        // 初始化密码器为加密模式，并设置密钥和初始化向量
        cipher.init(true, new ParametersWithIV(new KeyParameter(KEY.getBytes()), IV.getBytes()));
 
        // 将明文转换为字节数组
        byte[] input = plainText.getBytes();
        // 计算输出缓冲区的大小
        byte[] output = new byte[cipher.getOutputSize(input.length)];
        
        // 进行分步加密
        int length1 = cipher.processBytes(input, 0, input.length, output, 0);
        int length2 = cipher.doFinal(output, length1);
 
        // 返回加密后的内容，Base64 编码以便于传输和存储
        return Base64.getEncoder().encodeToString(output);
    }
 
    /**
     * 使用 SM4 算法对密文进行解密。
     *
     * @param encryptedText 加密后的 Base64 编码字符串
     * @return 解密后的明文字符串
     * @throws Exception 如果解密过程中发生错误
     */
    public static String decrypt(String encryptedText) throws Exception {
        // 创建一个带填充的缓冲块密码器，使用 CBC 模式和 SM4 引擎
        PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new SM4Engine()));
        
        // 初始化密码器为解密模式，并设置密钥和初始化向量
        cipher.init(false, new ParametersWithIV(new KeyParameter(KEY.getBytes()), IV.getBytes()));
 
        // 将 Base64 编码的密文解码为字节数组
        byte[] input = Base64.getDecoder().decode(encryptedText);
        // 计算输出缓冲区的大小
        byte[] output = new byte[cipher.getOutputSize(input.length)];
        
        // 进行分步解密
        int length1 = cipher.processBytes(input, 0, input.length, output, 0);
        int length2 = cipher.doFinal(output, length1);
 
        // 返回解密后的明文字符串
        return new String(output, 0, length1 + length2);
    }
 
}